--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tests/backend/test_audio_codec.py d64cd6baac9d816b92712e15c404615577af4b10 (d64cd6ba) Text, 7.86 KB
T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""Tests for the in-process audio decode/encode helpers.
These tests stand in for the previous ffmpeg subprocess pipeline.
Coverage is targeted at the public ``audio_codec`` API:
* ``decode_audio`` for WAV (built-in), miniaudio formats and OGG/Opus
* ``encode_pcm_to_ogg_opus`` round-trips
* ``encode_audio_to_ogg_opus`` for arbitrary inputs
* ``write_silence_ogg_opus`` for empty greetings/voicemails
* ``encode_audio_bytes_to_ogg_opus`` passthrough + decode-and-reencode
"""
Tff7b72import T7ee787io
Tff7b72import T7ee787math
Tff7b72import T7ee787os
Tff7b72import T7ee787struct
Tff7b72import T7ee787tempfile
Tff7b72import T7ee787wave
Tff7b72import T7ee787numpy Tff7b72as T7ee787np
Tff7b72import T7ee787pytest
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backend Tff7b72import Te6edf3audio_codec
Tff7b72def Td2a8ff_build_wav_pcm16Tb4b4b4(
Te6edf3samplerateTb4b4b4: Tffa657int Tff7b72= T79c0ff48000Tb4b4b4,
Te6edf3duration_secondsTb4b4b4: Tffa657float Tff7b72= T79c0ff0.4Tb4b4b4,
Te6edf3frequencyTb4b4b4: Tffa657float Tff7b72= T79c0ff440.0Tb4b4b4,
Te6edf3channelsTb4b4b4: Tffa657int Tff7b72= T79c0ff1Tb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657bytesTb4b4b4:
Te6edf3n_samples Tff7b72= Tffa657intTb4b4b4(Te6edf3samplerate Tff7b72* Te6edf3duration_secondsTb4b4b4)
Te6edf3buf Tff7b72= Te6edf3ioTff7b72.Td2a8ffBytesIOTb4b4b4(Tb4b4b4)
Tff7b72with Te6edf3waveTff7b72.Td2a8ffopenTb4b4b4(Te6edf3bufTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3wfTb4b4b4:
Te6edf3wfTff7b72.Td2a8ffsetnchannelsTb4b4b4(Te6edf3channelsTb4b4b4)
Te6edf3wfTff7b72.Td2a8ffsetsampwidthTb4b4b4(T79c0ff2Tb4b4b4)
Te6edf3wfTff7b72.Td2a8ffsetframerateTb4b4b4(Te6edf3samplerateTb4b4b4)
Te6edf3frames Tff7b72= Tffa657bytearrayTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Te6edf3n_samplesTb4b4b4)Tb4b4b4:
Te6edf3sample Tff7b72= Tffa657intTb4b4b4(
T79c0ff0.3 Tff7b72* T79c0ff32767 Tff7b72* Te6edf3mathTff7b72.Td2a8ffsinTb4b4b4(T79c0ff2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffpi Tff7b72* Te6edf3frequency Tff7b72* Tb4b4b4(Te6edf3i Tff7b72/ Te6edf3samplerateTb4b4b4)Tb4b4b4)
Tb4b4b4)
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(Te6edf3channelsTb4b4b4)Tb4b4b4:
Te6edf3framesTff7b72.Td2a8ffextendTb4b4b4(Te6edf3structTff7b72.Td2a8ffpackTb4b4b4(Ta5d6ff"Ta5d6ff<hTa5d6ff"Tb4b4b4, Te6edf3sampleTb4b4b4)Tb4b4b4)
Te6edf3wfTff7b72.Td2a8ffwriteframesTb4b4b4(Tffa657bytesTb4b4b4(Te6edf3framesTb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3bufTff7b72.Td2a8ffgetvalueTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ff_tmp_opus_pathTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Te6edf3tf Tff7b72= Te6edf3tempfileTff7b72.Td2a8ffNamedTemporaryFileTb4b4b4(Te6edf3suffixTff7b72=Ta5d6ff"Ta5d6ff.opusTa5d6ff"Tb4b4b4, Te6edf3deleteTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3tfTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3tfTff7b72.Td2a8ffname
Tff7b72def Td2a8fftest_decode_audio_wav_via_builtin_waveTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3wav Tff7b72= Te6edf3_build_wav_pcm16Tb4b4b4(Te6edf3samplerateTff7b72=T79c0ff48000Tb4b4b4, Te6edf3duration_secondsTff7b72=T79c0ff0.2Tb4b4b4)
Te6edf3decoded Tff7b72= Te6edf3audio_codecTff7b72.Td2a8ffdecode_audioTb4b4b4(Te6edf3wavTb4b4b4)
Tff7b72assert Te6edf3decodedTff7b72.Td2a8ffsamplerate Tff7b72== T79c0ff48000
Tff7b72assert Te6edf3decodedTff7b72.Td2a8ffchannels Tff7b72== T79c0ff1
Tff7b72assert Te6edf3decodedTff7b72.Td2a8ffsamplesTff7b72.Td2a8ffdtype Tff7b72== Te6edf3npTff7b72.Td2a8fffloat32
Tff7b72assert Te6edf3decodedTff7b72.Td2a8ffsamplesTff7b72.Td2a8ffshapeTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72== T79c0ff1
Tff7b72assert Te6edf3decodedTff7b72.Td2a8ffsamplesTff7b72.Td2a8ffshapeTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Tffa657intTb4b4b4(T79c0ff48000 Tff7b72* T79c0ff0.2Tb4b4b4)
Tff7b72def Td2a8fftest_decode_audio_accepts_path_and_filelikeTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3wav Tff7b72= Te6edf3_build_wav_pcm16Tb4b4b4(Tb4b4b4)
Te6edf3path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffx.wavTa5d6ff"
Te6edf3pathTff7b72.Td2a8ffwrite_bytesTb4b4b4(Te6edf3wavTb4b4b4)
Te6edf3from_path Tff7b72= Te6edf3audio_codecTff7b72.Td2a8ffdecode_audioTb4b4b4(Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4)
Te6edf3from_filelike Tff7b72= Te6edf3audio_codecTff7b72.Td2a8ffdecode_audioTb4b4b4(Te6edf3ioTff7b72.Td2a8ffBytesIOTb4b4b4(Te6edf3wavTb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3from_pathTff7b72.Td2a8ffsamplesTff7b72.Td2a8ffshape Tff7b72== Te6edf3from_filelikeTff7b72.Td2a8ffsamplesTff7b72.Td2a8ffshape
Tff7b72def Td2a8fftest_decode_audio_invalid_payload_raisesTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3pytestTff7b72.Td2a8ffraisesTb4b4b4(Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Te6edf3audio_codecTff7b72.Td2a8ffdecode_audioTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffnot audio at allTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_encode_pcm_to_ogg_opus_writes_valid_containerTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3out Tff7b72= Te6edf3_tmp_opus_pathTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3samples Tff7b72= Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(Tb4b4b4(T79c0ff48000Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)
Te6edf3audio_codecTff7b72.Td2a8ffencode_pcm_to_ogg_opusTb4b4b4(Te6edf3samplesTb4b4b4, T79c0ff48000Tb4b4b4, T79c0ff1Tb4b4b4, Te6edf3outTb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3outTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72assert Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(T79c0ff4Tb4b4b4) Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"
Tff7b72assert Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetsizeTb4b4b4(Te6edf3outTb4b4b4) Tff7b72> T79c0ff0
Tff7b72finallyTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3outTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3outTb4b4b4)
Tff7b72def Td2a8fftest_encode_pcm_to_ogg_opus_resamples_arbitrary_rateTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Inputs at any rate (here 22050 stereo) must be normalized before encode."""
Te6edf3out Tff7b72= Te6edf3_tmp_opus_pathTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3samplerate Tff7b72= T79c0ff22050
Te6edf3channels Tff7b72= T79c0ff2
Te6edf3n Tff7b72= Te6edf3samplerate
Te6edf3samples Tff7b72= Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(Tb4b4b4(Te6edf3nTb4b4b4, Te6edf3channelsTb4b4b4)Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Te6edf3nTb4b4b4)Tb4b4b4:
Te6edf3v Tff7b72= T79c0ff0.2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffsinTb4b4b4(T79c0ff2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffpi Tff7b72* T79c0ff880.0 Tff7b72* Tb4b4b4(Te6edf3i Tff7b72/ Te6edf3samplerateTb4b4b4)Tb4b4b4)
Te6edf3samplesTb4b4b4[Te6edf3iTb4b4b4, T79c0ff0Tb4b4b4] Tff7b72= Te6edf3v
Te6edf3samplesTb4b4b4[Te6edf3iTb4b4b4, T79c0ff1Tb4b4b4] Tff7b72= Te6edf3v
Te6edf3audio_codecTff7b72.Td2a8ffencode_pcm_to_ogg_opusTb4b4b4(Te6edf3samplesTb4b4b4, Te6edf3samplerateTb4b4b4, Te6edf3channelsTb4b4b4, Te6edf3outTb4b4b4)
Tff7b72assert Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetsizeTb4b4b4(Te6edf3outTb4b4b4) Tff7b72> T79c0ff0
Tff7b72with Tffa657openTb4b4b4(Te6edf3outTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72assert Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(T79c0ff4Tb4b4b4) Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"
Tff7b72finallyTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3outTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3outTb4b4b4)
Tff7b72def Td2a8fftest_encode_audio_to_ogg_opus_decodes_and_reencodesTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3wav Tff7b72= Te6edf3_build_wav_pcm16Tb4b4b4(Te6edf3duration_secondsTff7b72=T79c0ff0.3Tb4b4b4)
Te6edf3src Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffin.wavTa5d6ff"
Te6edf3srcTff7b72.Td2a8ffwrite_bytesTb4b4b4(Te6edf3wavTb4b4b4)
Te6edf3dst Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffout.opusTa5d6ff"
Te6edf3audio_codecTff7b72.Td2a8ffencode_audio_to_ogg_opusTb4b4b4(Tffa657strTb4b4b4(Te6edf3srcTb4b4b4)Tb4b4b4, Tffa657strTb4b4b4(Te6edf3dstTb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3dstTff7b72.Td2a8ffexistsTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3dstTff7b72.Td2a8ffread_bytesTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"
Tff7b72def Td2a8fftest_encode_audio_bytes_to_ogg_opus_returns_passthrough_for_oggTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3ogg Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff" Tff7b72+ Ta5d6ffbTa5d6ff"Tffea00\x00Ta5d6ff" Tff7b72* T79c0ff32
Tff7b72assert Te6edf3audio_codecTff7b72.Td2a8ffencode_audio_bytes_to_ogg_opusTb4b4b4(Te6edf3oggTb4b4b4) Tff7b72is Te6edf3ogg
Tff7b72def Td2a8fftest_encode_audio_bytes_to_ogg_opus_decodes_wavTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3wav Tff7b72= Te6edf3_build_wav_pcm16Tb4b4b4(Tb4b4b4)
Te6edf3encoded Tff7b72= Te6edf3audio_codecTff7b72.Td2a8ffencode_audio_bytes_to_ogg_opusTb4b4b4(Te6edf3wavTb4b4b4)
Tff7b72assert Te6edf3encoded Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3encodedTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3encodedTb4b4b4) Tff7b72< Tffa657lenTb4b4b4(Te6edf3wavTb4b4b4)
Tff7b72def Td2a8fftest_encode_audio_bytes_to_ogg_opus_returns_none_for_garbageTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3audio_codecTff7b72.Td2a8ffencode_audio_bytes_to_ogg_opusTb4b4b4(Ta5d6ffbTa5d6ff"Tffea00\x00Ta5d6ff" Tff7b72* T79c0ff32Tb4b4b4) Tff7b72is Tff7b72None
Tff7b72def Td2a8fftest_write_silence_ogg_opusTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3dst Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffsilence.opusTa5d6ff"
Te6edf3audio_codecTff7b72.Td2a8ffwrite_silence_ogg_opusTb4b4b4(Tffa657strTb4b4b4(Te6edf3dstTb4b4b4)Tb4b4b4, Te6edf3secondsTff7b72=T79c0ff0.5Tb4b4b4)
Tff7b72assert Te6edf3dstTff7b72.Td2a8ffexistsTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3dstTff7b72.Td2a8ffread_bytesTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"
Tff7b72assert Te6edf3dstTff7b72.Td2a8ffstatTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffst_size Tff7b72> T79c0ff0
Tff7b72def Td2a8fftest_is_ogg_opus_bytes_helperTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3audio_codecTff7b72.Td2a8ffis_ogg_opus_bytesTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffOggSTffea00\x01Tffea00\x02Tffea00\x03Tffea00\x04Ta5d6ff"Tb4b4b4)
Tff7b72assert Tff7b72not Te6edf3audio_codecTff7b72.Td2a8ffis_ogg_opus_bytesTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffRIFFsomethingTa5d6ff"Tb4b4b4)
Tff7b72assert Tff7b72not Te6edf3audio_codecTff7b72.Td2a8ffis_ogg_opus_bytesTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72def Td2a8ff_ogg_opus_duration_secondsTb4b4b4(Te6edf3pathTb4b4b4: Tffa657strTb4b4b4) Tff7b72-Tff7b72> Tffa657floatTb4b4b4:
T8b949e"""Compute encoded duration from the Ogg granule positions and Opus pre-skip.
Lets us assert the encoded file is exactly as long as the input PCM
without depending on libopusfile being installed for decode.
"""
Tff7b72with Tffa657openTb4b4b4(Te6edf3pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3data Tff7b72= Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3last_gp Tff7b72= T79c0ff0
Te6edf3i Tff7b72= T79c0ff0
Tff7b72while Te6edf3i Tff7b72+ T79c0ff27 Tff7b72<Tff7b72= Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3dataTb4b4b4[Te6edf3i Tb4b4b4: Te6edf3i Tff7b72+ T79c0ff4Tb4b4b4] Tff7b72!= Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"Tb4b4b4:
Te6edf3i Tff7b72+Tff7b72= T79c0ff1
Tff7b72continue
Te6edf3gp Tff7b72= Te6edf3structTff7b72.Td2a8ffunpackTb4b4b4(Ta5d6ff"Ta5d6ff<qTa5d6ff"Tb4b4b4, Te6edf3dataTb4b4b4[Te6edf3i Tff7b72+ T79c0ff6 Tb4b4b4: Te6edf3i Tff7b72+ T79c0ff14Tb4b4b4]Tb4b4b4)Tb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3nsegs Tff7b72= Te6edf3dataTb4b4b4[Te6edf3i Tff7b72+ T79c0ff26Tb4b4b4]
Tff7b72if Te6edf3i Tff7b72+ T79c0ff27 Tff7b72+ Te6edf3nsegs Tff7b72> Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72break
Te6edf3body Tff7b72= Tffa657sumTb4b4b4(Te6edf3dataTb4b4b4[Te6edf3i Tff7b72+ T79c0ff27 Tb4b4b4: Te6edf3i Tff7b72+ T79c0ff27 Tff7b72+ Te6edf3nsegsTb4b4b4]Tb4b4b4)
Te6edf3i Tff7b72+Tff7b72= T79c0ff27 Tff7b72+ Te6edf3nsegs Tff7b72+ Te6edf3body
Tff7b72if Te6edf3gp Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3last_gp Tff7b72= Te6edf3gp
Te6edf3head Tff7b72= Te6edf3dataTff7b72.Td2a8fffindTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffOpusHeadTa5d6ff"Tb4b4b4)
Te6edf3pre_skip Tff7b72= Te6edf3structTff7b72.Td2a8ffunpackTb4b4b4(Ta5d6ff"Ta5d6ff<HTa5d6ff"Tb4b4b4, Te6edf3dataTb4b4b4[Te6edf3head Tff7b72+ T79c0ff10 Tb4b4b4: Te6edf3head Tff7b72+ T79c0ff12Tb4b4b4]Tb4b4b4)Tb4b4b4[T79c0ff0Tb4b4b4] Tff7b72if Te6edf3head Tff7b72>Tff7b72= T79c0ff0 Tff7b72else T79c0ff0
Tff7b72return Tffa657maxTb4b4b4(T79c0ff0.0Tb4b4b4, Tb4b4b4(Te6edf3last_gp Tff7b72- Te6edf3pre_skipTb4b4b4) Tff7b72/ T79c0ff48000.0Tb4b4b4)
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffparametrizeTb4b4b4(Ta5d6ff"Ta5d6ffduration_secondsTa5d6ff"Tb4b4b4, Tb4b4b4[T79c0ff0.3Tb4b4b4, T79c0ff1.0Tb4b4b4, T79c0ff5.0Tb4b4b4, T79c0ff10.0Tb4b4b4]Tb4b4b4)
Tff7b72def Td2a8fftest_encode_pcm_to_ogg_opus_preserves_durationTb4b4b4(Te6edf3duration_secondsTb4b4b4)Tb4b4b4:
T8b949e"""Regression test: encoded length must match the input length.
The previous OpusFileSink-based path silently dropped frames once the
threaded sink's bounded deque overflowed (any clip >~3.8s came out
truncated to ~4.5s) and tacked 600 ms of silence onto the tail of
every clip. A trimmed ringtone therefore never matched the user's
selection. The synchronous OggOpusWriter path must be exact.
"""
Te6edf3out Tff7b72= Te6edf3_tmp_opus_pathTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3sr Tff7b72= T79c0ff48000
Te6edf3n Tff7b72= Tffa657intTb4b4b4(Te6edf3sr Tff7b72* Te6edf3duration_secondsTb4b4b4)
Te6edf3t Tff7b72= Te6edf3npTff7b72.Td2a8ffarangeTb4b4b4(Te6edf3nTb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4) Tff7b72/ Te6edf3sr
Te6edf3samples Tff7b72= Tb4b4b4(
Tb4b4b4(T79c0ff0.3 Tff7b72* Te6edf3npTff7b72.Td2a8ffsinTb4b4b4(T79c0ff2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffpi Tff7b72* T79c0ff440.0 Tff7b72* Te6edf3tTb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)Tff7b72.Td2a8ffreshapeTb4b4b4(Tff7b72-T79c0ff1Tb4b4b4, T79c0ff1Tb4b4b4)
Tb4b4b4)
Te6edf3audio_codecTff7b72.Td2a8ffencode_pcm_to_ogg_opusTb4b4b4(Te6edf3samplesTb4b4b4, Te6edf3srTb4b4b4, T79c0ff1Tb4b4b4, Te6edf3outTb4b4b4)
Te6edf3encoded Tff7b72= Te6edf3_ogg_opus_duration_secondsTb4b4b4(Te6edf3outTb4b4b4)
Tff7b72assert Tffa657absTb4b4b4(Te6edf3encoded Tff7b72- Te6edf3duration_secondsTb4b4b4) Tff7b72< T79c0ff0.001Tb4b4b4, Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffexpected Tffd700{Te6edf3duration_secondsTffd700}Ta5d6ffs, got Tffd700{Te6edf3encodedTffd700}Ta5d6ffsTa5d6ff"
Tb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3outTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3outTb4b4b4)
Tff7b72def Td2a8fftest_encode_pcm_to_ogg_opus_audio_profile_keeps_stereoTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""``PROFILE_AUDIO_MAX`` must keep stereo input as stereo, not collapse to mono."""
Te6edf3out Tff7b72= Te6edf3_tmp_opus_pathTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72from T7ee787LXSTT7ee787.T7ee787Codecs Tff7b72import Te6edf3Opus
Te6edf3sr Tff7b72= T79c0ff48000
Te6edf3n Tff7b72= Te6edf3sr T8b949e# 1 second
Te6edf3samples Tff7b72= Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(Tb4b4b4(Te6edf3nTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)
Te6edf3t Tff7b72= Te6edf3npTff7b72.Td2a8ffarangeTb4b4b4(Te6edf3nTb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4) Tff7b72/ Te6edf3sr
Te6edf3samplesTb4b4b4[Tb4b4b4:Tb4b4b4, T79c0ff0Tb4b4b4] Tff7b72= T79c0ff0.3 Tff7b72* Te6edf3npTff7b72.Td2a8ffsinTb4b4b4(T79c0ff2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffpi Tff7b72* T79c0ff440.0 Tff7b72* Te6edf3tTb4b4b4)
Te6edf3samplesTb4b4b4[Tb4b4b4:Tb4b4b4, T79c0ff1Tb4b4b4] Tff7b72= T79c0ff0.3 Tff7b72* Te6edf3npTff7b72.Td2a8ffsinTb4b4b4(T79c0ff2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffpi Tff7b72* T79c0ff660.0 Tff7b72* Te6edf3tTb4b4b4)
Te6edf3audio_codecTff7b72.Td2a8ffencode_pcm_to_ogg_opusTb4b4b4(
Te6edf3samplesTb4b4b4, Te6edf3srTb4b4b4, T79c0ff2Tb4b4b4, Te6edf3outTb4b4b4, Te6edf3profileTff7b72=Te6edf3OpusTff7b72.Td2a8ffPROFILE_AUDIO_MAX
Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3outTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3data Tff7b72= Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3head Tff7b72= Te6edf3dataTff7b72.Td2a8fffindTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffOpusHeadTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3head Tff7b72>Tff7b72= T79c0ff0
Te6edf3channels Tff7b72= Te6edf3dataTb4b4b4[Te6edf3head Tff7b72+ T79c0ff9Tb4b4b4]
Tff7b72assert Te6edf3channels Tff7b72== T79c0ff2
Tff7b72assert Te6edf3_ogg_opus_duration_secondsTb4b4b4(Te6edf3outTb4b4b4) Tff7b72== Te6edf3pytestTff7b72.Td2a8ffapproxTb4b4b4(T79c0ff1.0Tb4b4b4, Tffa657absTff7b72=T79c0ff0.001Tb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3outTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3outTb4b4b4)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────